﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Xml.Linq;

namespace Silverlight
{
    /// <summary>
    /// Provides DataRowCollection functionality
    /// </summary>
    public class DataRowCollection : Collection<DataRow>
    {
        #region Events
        /// <summary>
        /// Value is changing inside column
        /// </summary>
        public event EventHandler<DataSetEventArgs> FieldValueChanging;

        /// <summary>
        /// INotifyPropertyChanged interface implementation
        /// </summary>
        internal event PropertyChangedEventHandler PropertyChanged;
        #endregion

        #region Constructors
        /// <summary>
        /// Default constructor
        /// </summary>
        internal DataRowCollection()
        {
        }
        #endregion

        #region Methods
        /// <summary>
        /// Adds row to collection
        /// </summary>
        /// <param name="dataRow">Row for adding</param>
        /// <returns>Added row</returns>
        public new DataRow Add(DataRow dataRow)
        {
            // Validate argument
            if (dataRow == null)
            {
                throw new ArgumentNullException("dataRow");
            }

            // Vallidate required fields
            for (int i = 0; i < dataRow.Table.Columns.Count; i++)
            {
                if (!dataRow.Table.Columns[i].AllowDBNull && dataRow.ItemArray[i].Value == null)
                {
                    throw new InvalidOperationException("Value cannot be null inside required \"" + dataRow.Table.Columns[i].ColumnName + "\" field");
                }
            }

            dataRow.Index = base.Count;
            dataRow.EndEdit();
            dataRow.RowState = DataRowState.Added;
            dataRow.RowVersion = DataRowVersion.Current;
            dataRow.RowDeleted += new EventHandler<EventArgs>(DataRow_RowDeleted);
            dataRow.FieldValueChanging += new EventHandler<DataSetEventArgs>(DataRow_FieldValueChanging);
            dataRow.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(dataRow_PropertyChanged);
            base.Add(dataRow);
            return dataRow;
        }
        #endregion

        #region Event Handlers
        /// <summary>
        /// Handles DataRow.RowDeleted event
        /// </summary>
        /// <param name="sender">Event source</param>
        /// <param name="e">Event arguments</param>
        void DataRow_RowDeleted(object sender, EventArgs e)
        {
            // Remove added row when it was deleted
            DataRow dataRow = (DataRow)sender;
            dataRow.RowDeleted -= DataRow_RowDeleted;
            dataRow.FieldValueChanging -= DataRow_FieldValueChanging;
            dataRow.PropertyChanged -= dataRow_PropertyChanged;
            base.Remove(dataRow);
        }

        /// <summary>
        /// Handles DataRow.FieldValueChanging event
        /// </summary>
        /// <param name="sender">Event source</param>
        /// <param name="e">Event arguments</param>
        void DataRow_FieldValueChanging(object sender, DataSetEventArgs e)
        {
            if (FieldValueChanging != null)
            {
                FieldValueChanging(sender, e);
            }
        }

        /// <summary>
        /// Handles DataField.PropertyChanged event
        /// </summary>
        /// <param name="sender">Event source</param>
        /// <param name="e">Event arguments</param>
        void dataRow_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (PropertyChanged != null)
            {
                if (e.PropertyName == "HasErrors")
                {
                    PropertyChanged(this, e);
                }
            }
        }
        #endregion
    }
}
